use cosmwasm_std::{HumanAddr, StdError, StdResult, Storage, Uint128};
use cosmwasm_storage::{Bucket, ReadonlyBucket};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

pub const STAKERS_KEY: &[u8] = b"stakers";

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Staker {
    pub address: HumanAddr,
    pub pool_id: u8,
    pub stake_amount: Uint128,
    pub reward: Uint128,
    pub last_block: u64,
    pub reward_dept: Uint128,
    pub stake_nfttoken_ids: Vec<String>,
}

pub fn store_staker<S: Storage>(storage: &mut S, data: &Staker) -> StdResult<()> {
    let key = &[
        data.pool_id.to_string().as_bytes(),
        data.address.to_string().as_bytes(),
    ]
    .concat();
    let mut staker_bucket: Bucket<S, Staker> = Bucket::new(STAKERS_KEY, storage);
    staker_bucket.save(key, &data)?;

    Ok(())
}

pub fn read_staker_by_address<S: Storage>(
    storage: &S,
    pool_id: u8,
    address: HumanAddr,
) -> StdResult<Staker> {
    let staker_bucket: ReadonlyBucket<S, Staker> = ReadonlyBucket::new(STAKERS_KEY, storage);
    let key = &[
        pool_id.to_string().as_bytes(),
        address.to_string().as_bytes(),
    ]
    .concat();

    match staker_bucket.load(key) {
        Ok(v) => Ok(v),
        Err(_e) => Err(StdError::generic_err("no staker data stored")),
    }
}
